load("//tools/lint:lint.bzl", "add_lint_tests")
load(
    "//tools/skylark:drake_cc.bzl",
    "drake_cc_googletest",
    "drake_cc_library",
    "drake_cc_package_library",
)

package(
    default_visibility = ["//visibility:public"],
)

drake_cc_package_library(
    name = "tree",
    visibility = ["//visibility:public"],
    deps = [
        ":articulated_body_inertia",
        ":geometry_spatial_inertia",
        ":multibody_tree_caches",
        ":multibody_tree_core",
        ":multibody_tree_indexes",
        ":multibody_tree_topology",
        ":rotational_inertia",
        ":scoped_name",
        ":spatial_inertia",
        ":unit_inertia",
    ],
)

drake_cc_library(
    name = "multibody_tree_indexes",
    srcs = [],
    hdrs = [
        "multibody_tree_indexes.h",
    ],
    deps = [
        "//common:identifier",
        "//common:type_safe_index",
    ],
)

drake_cc_library(
    name = "multibody_tree_topology",
    srcs = [
        "multibody_tree_topology.cc",
    ],
    hdrs = [
        "multibody_tree_topology.h",
    ],
    deps = [
        ":multibody_tree_indexes",
        "//multibody/topology",
    ],
)

drake_cc_library(
    name = "multibody_tree_caches",
    srcs = [
        "acceleration_kinematics_cache.cc",
        "articulated_body_force_cache.cc",
        "articulated_body_inertia_cache.cc",
        "frame_body_pose_cache.cc",
        "position_kinematics_cache.cc",
        "velocity_kinematics_cache.cc",
    ],
    hdrs = [
        "acceleration_kinematics_cache.h",
        "articulated_body_force_cache.h",
        "articulated_body_inertia_cache.h",
        "frame_body_pose_cache.h",
        "position_kinematics_cache.h",
        "velocity_kinematics_cache.h",
    ],
    deps = [
        ":articulated_body_inertia",
        ":multibody_tree_topology",
        "//common:autodiff",
        "//multibody/math:spatial_algebra",
        "//systems/framework:leaf_context",
    ],
)

drake_cc_library(
    name = "multibody_tree_core",
    srcs = [
        "ball_rpy_joint.cc",
        "body_node.cc",
        "body_node_impl.cc",
        "body_node_impl_mass_matrix.cc",
        "curvilinear_joint.cc",
        "curvilinear_mobilizer.cc",
        "door_hinge.cc",
        "element_collection.cc",
        "fixed_offset_frame.cc",
        "force_element.cc",
        "frame.cc",
        "joint.cc",
        "joint_actuator.cc",
        "linear_bushing_roll_pitch_yaw.cc",
        "linear_spring_damper.cc",
        "mobilizer.cc",
        "mobilizer_impl.cc",
        "model_instance.cc",
        "multibody_element.cc",
        "multibody_forces.cc",
        "multibody_tree.cc",
        "multibody_tree_system.cc",
        "planar_joint.cc",
        "planar_mobilizer.cc",
        "prismatic_joint.cc",
        "prismatic_mobilizer.cc",
        "prismatic_spring.cc",
        "quaternion_floating_joint.cc",
        "quaternion_floating_mobilizer.cc",
        "revolute_joint.cc",
        "revolute_mobilizer.cc",
        "revolute_spring.cc",
        "rigid_body.cc",
        "rpy_ball_mobilizer.cc",
        "rpy_floating_joint.cc",
        "rpy_floating_mobilizer.cc",
        "screw_joint.cc",
        "screw_mobilizer.cc",
        "uniform_gravity_field_element.cc",
        "universal_joint.cc",
        "universal_mobilizer.cc",
        "weld_joint.cc",
        "weld_mobilizer.cc",
    ],
    hdrs = [
        "ball_rpy_joint.h",
        "body_node.h",
        "body_node_impl.h",
        "body_node_world.h",
        "curvilinear_joint.h",
        "curvilinear_mobilizer.h",
        "door_hinge.h",
        "element_collection.h",
        "fixed_offset_frame.h",
        "force_element.h",
        "frame.h",
        "joint.h",
        "joint_actuator.h",
        "linear_bushing_roll_pitch_yaw.h",
        "linear_spring_damper.h",
        "mobilizer.h",
        "mobilizer_impl.h",
        "model_instance.h",
        "multibody_element.h",
        "multibody_forces.h",
        "multibody_tree.h",
        "multibody_tree-inl.h",
        "multibody_tree_system.h",
        "parameter_conversion.h",
        "planar_joint.h",
        "planar_mobilizer.h",
        "prismatic_joint.h",
        "prismatic_mobilizer.h",
        "prismatic_spring.h",
        "quaternion_floating_joint.h",
        "quaternion_floating_mobilizer.h",
        "revolute_joint.h",
        "revolute_mobilizer.h",
        "revolute_spring.h",
        "rigid_body.h",
        "rpy_ball_mobilizer.h",
        "rpy_floating_joint.h",
        "rpy_floating_mobilizer.h",
        "screw_joint.h",
        "screw_mobilizer.h",
        "uniform_gravity_field_element.h",
        "universal_joint.h",
        "universal_mobilizer.h",
        "weld_joint.h",
        "weld_mobilizer.h",
    ],
    # Hide this library outside of this package; users should depend on
    # "//multibody/tree" broadly, not just ":multibody_tree_core".
    visibility = ["//visibility:private"],
    deps = [
        ":multibody_tree_caches",
        ":multibody_tree_indexes",
        ":scoped_name",
        ":spatial_inertia",
        "//common:default_scalars",
        "//common:name_value",
        "//common:nice_type_name",
        "//common:string_container",
        "//common:unused",
        "//common/trajectories:piecewise_constant_curvature_trajectory",
        "//math:geometric_transform",
        "//multibody/topology",
        "//systems/framework:leaf_system",
    ],
)

drake_cc_library(
    name = "rotational_inertia",
    srcs = ["rotational_inertia.cc"],
    hdrs = ["rotational_inertia.h"],
    deps = [
        "//common:default_scalars",
        "//common:drake_bool",
        "//common:essential",
        "//common:extract_double",
        "//math:geometric_transform",
    ],
)

drake_cc_library(
    name = "scoped_name",
    srcs = ["scoped_name.cc"],
    hdrs = ["scoped_name.h"],
    deps = [
        ":multibody_tree_indexes",
        "//common:essential",
        "//common:reset_after_move",
    ],
)

drake_cc_library(
    name = "spatial_inertia",
    srcs = ["spatial_inertia.cc"],
    hdrs = ["spatial_inertia.h"],
    deps = [
        ":rotational_inertia",
        ":unit_inertia",
        "//common:default_scalars",
        "//common:drake_bool",
        "//common:essential",
        "//math:geometric_transform",
        "//math:vector3_util",
        "//multibody/math:spatial_algebra",
    ],
)

drake_cc_library(
    name = "unit_inertia",
    srcs = ["unit_inertia.cc"],
    hdrs = ["unit_inertia.h"],
    deps = [
        ":rotational_inertia",
        "//common:default_scalars",
        "//common:essential",
        "//math:geometric_transform",
        "//math:vector3_util",
    ],
)

drake_cc_library(
    name = "articulated_body_inertia",
    srcs = ["articulated_body_inertia.cc"],
    hdrs = ["articulated_body_inertia.h"],
    deps = [
        ":spatial_inertia",
        "//common:default_scalars",
        "//common:essential",
        "//common:nice_type_name",
        "//math:linear_solve",
        "//math:vector3_util",
        "//multibody/math:spatial_algebra",
    ],
)

drake_cc_library(
    name = "geometry_spatial_inertia",
    srcs = ["geometry_spatial_inertia.cc"],
    hdrs = ["geometry_spatial_inertia.h"],
    deps = [
        ":spatial_inertia",
        "//common:overloaded",
        "//geometry:shape_specification",
        "//geometry/proximity:make_mesh_from_vtk",
        "//geometry/proximity:obj_to_surface_mesh",
        "//geometry/proximity:polygon_to_triangle_mesh",
        "//geometry/proximity:triangle_surface_mesh",
        "//geometry/proximity:volume_to_surface_mesh",
    ],
)

# === test/ ===

drake_cc_library(
    name = "free_rotating_body_plant",
    testonly = 1,
    srcs = ["test/free_rotating_body_plant.cc"],
    hdrs = ["test/free_rotating_body_plant.h"],
    deps = [
        ":tree",
        "//common:default_scalars",
        "//systems/framework",
    ],
)

drake_cc_googletest(
    name = "body_node_test",
    deps = [
        ":multibody_tree_core",
        ":rotational_inertia",
        "//common/test_utilities:expect_throws_message",
    ],
)

drake_cc_googletest(
    name = "element_collection_test",
    deps = [
        ":multibody_tree_core",
        "//common/test_utilities:expect_throws_message",
    ],
)

drake_cc_googletest(
    name = "free_rotating_body_test",
    srcs = [
        "test/free_rotating_body_test.cc",
    ],
    deps = [
        ":free_rotating_body_plant",
        "//common/test_utilities:eigen_matrix_compare",
        "//multibody/benchmarks/free_body",
        "//systems/analysis:runge_kutta3_integrator",
        "//systems/analysis:simulator",
    ],
)

drake_cc_googletest(
    name = "scoped_name_test",
    deps = [
        ":scoped_name",
    ],
)

drake_cc_googletest(
    name = "tree_from_mobilizers_test",
    # Test timeout increased to not timeout in debug and when run with
    # Valgrind.
    timeout = "moderate",
    deps = [
        ":tree",
        "//common/test_utilities:eigen_matrix_compare",
        "//common/test_utilities:expect_no_throw",
        "//math:autodiff",
        "//math:gradient",
        "//multibody/benchmarks/acrobot:analytical_acrobot",
    ],
)

drake_cc_googletest(
    name = "tree_from_joints_test",
    deps = [
        ":tree",
        "//common/test_utilities:eigen_matrix_compare",
        "//multibody/benchmarks/acrobot:analytical_acrobot",
    ],
)

drake_cc_googletest(
    name = "frames_test",
    deps = [
        ":tree",
        "//common/test_utilities:expect_throws_message",
    ],
)

drake_cc_googletest(
    name = "model_instance_test",
    deps = [
        ":tree",
        "//common/test_utilities:eigen_matrix_compare",
        "//common/test_utilities:expect_throws_message",
    ],
)

drake_cc_googletest(
    name = "multibody_forces_test",
    deps = [
        ":tree",
        "//common/test_utilities:eigen_matrix_compare",
    ],
)

drake_cc_googletest(
    name = "multibody_tree_test",
    deps = [
        ":tree",
        "//common/test_utilities",
        "//common/test_utilities:limit_malloc",
        "//math:gradient",
        "//multibody/benchmarks/kuka_iiwa_robot",
        "//multibody/benchmarks/kuka_iiwa_robot/MG:MG_kuka_robot_lib",
    ],
)

drake_cc_googletest(
    name = "multibody_tree_creation_test",
    deps = [
        ":tree",
        "//common/test_utilities",
    ],
)

drake_cc_googletest(
    name = "multibody_tree_indexes_test",
    deps = [
        ":multibody_tree_indexes",
        "//common/test_utilities:expect_no_throw",
    ],
)

drake_cc_googletest(
    name = "rotational_inertia_test",
    deps = [
        ":rotational_inertia",
        "//common:autodiff",
        "//common/test_utilities:eigen_matrix_compare",
        "//common/test_utilities:expect_no_throw",
        "//common/test_utilities:expect_throws_message",
        "//math:geometric_transform",
        "//math:gradient",
    ],
)

drake_cc_googletest(
    name = "spatial_inertia_test",
    deps = [
        ":spatial_inertia",
        "//common/test_utilities:eigen_matrix_compare",
        "//common/test_utilities:expect_no_throw",
        "//common/test_utilities:expect_throws_message",
        "//math:geometric_transform",
        "//math:gradient",
    ],
)

drake_cc_googletest(
    name = "unit_inertia_test",
    deps = [
        ":unit_inertia",
        "//common/test_utilities:eigen_matrix_compare",
        "//common/test_utilities:expect_throws_message",
        "//math:geometric_transform",
        "//math:gradient",
    ],
)

drake_cc_library(
    name = "mobilizer_tester",
    testonly = 1,
    hdrs = ["test/mobilizer_tester.h"],
    deps = [
        ":tree",
    ],
)

drake_cc_googletest(
    name = "curvilinear_mobilizer_test",
    deps = [
        ":mobilizer_tester",
        ":tree",
        "//common/test_utilities:eigen_matrix_compare",
    ],
)

drake_cc_googletest(
    name = "planar_mobilizer_test",
    deps = [
        ":mobilizer_tester",
        ":tree",
        "//common/test_utilities:eigen_matrix_compare",
    ],
)

drake_cc_googletest(
    name = "prismatic_mobilizer_test",
    deps = [
        ":mobilizer_tester",
        ":tree",
        "//common/test_utilities:eigen_matrix_compare",
    ],
)

drake_cc_googletest(
    name = "quaternion_floating_mobilizer_test",
    deps = [
        ":mobilizer_tester",
        ":tree",
        "//common/test_utilities:eigen_matrix_compare",
        "//common/test_utilities:expect_throws_message",
        "//math:geometric_transform",
    ],
)

drake_cc_googletest(
    name = "revolute_mobilizer_test",
    deps = [
        ":mobilizer_tester",
        ":tree",
        "//common/test_utilities:eigen_matrix_compare",
    ],
)

drake_cc_googletest(
    name = "screw_mobilizer_test",
    deps = [
        ":mobilizer_tester",
        ":tree",
        "//common/test_utilities:eigen_matrix_compare",
    ],
)

drake_cc_googletest(
    name = "rpy_ball_mobilizer_test",
    deps = [
        ":mobilizer_tester",
        ":tree",
        "//common/test_utilities:eigen_matrix_compare",
        "//common/test_utilities:expect_throws_message",
    ],
)

drake_cc_googletest(
    name = "rpy_floating_mobilizer_test",
    deps = [
        ":mobilizer_tester",
        ":tree",
        "//common/test_utilities:eigen_matrix_compare",
        "//common/test_utilities:expect_throws_message",
    ],
)

drake_cc_googletest(
    name = "universal_mobilizer_test",
    deps = [
        ":mobilizer_tester",
        ":tree",
        "//common/test_utilities:eigen_matrix_compare",
    ],
)

drake_cc_googletest(
    name = "weld_mobilizer_test",
    deps = [
        ":mobilizer_tester",
        ":tree",
        "//common/test_utilities:eigen_matrix_compare",
    ],
)

drake_cc_googletest(
    name = "rigid_body_test",
    deps = [
        ":tree",
        "//common/test_utilities:eigen_matrix_compare",
        "//common/test_utilities:expect_throws_message",
        "//systems/framework:context",
    ],
)

drake_cc_googletest(
    name = "articulated_body_inertia_test",
    deps = [
        ":tree",
        "//common/test_utilities:expect_no_throw",
        "//common/test_utilities:expect_throws_message",
        "//math:autodiff",
        "//math:gradient",
    ],
)

drake_cc_googletest(
    name = "articulated_body_algorithm_test",
    deps = [
        ":tree",
        "//common/test_utilities:eigen_matrix_compare",
    ],
)

drake_cc_googletest(
    name = "linear_bushing_roll_pitch_yaw_test",
    deps = [
        ":tree",
        "//common/test_utilities:eigen_matrix_compare",
        "//common/test_utilities:expect_no_throw",
        "//common/test_utilities:expect_throws_message",
        "//multibody/plant",
        "//systems/framework",
    ],
)

drake_cc_googletest(
    name = "linear_spring_damper_test",
    deps = [
        "//common/test_utilities:eigen_matrix_compare",
        "//common/test_utilities:expect_throws_message",
        "//multibody/plant",
        "//systems/framework:context",
    ],
)

drake_cc_googletest(
    name = "door_hinge_test",
    timeout = "moderate",
    shard_count = 2,
    deps = [
        "//multibody/plant",
        "//systems/analysis:initial_value_problem",
        "//systems/analysis:simulator",
    ],
)

drake_cc_googletest(
    name = "prismatic_spring_test",
    deps = [
        ":tree",
        "//common/test_utilities:eigen_matrix_compare",
        "//systems/framework:context",
    ],
)

drake_cc_googletest(
    name = "revolute_spring_test",
    deps = [
        ":tree",
        "//common/test_utilities:eigen_matrix_compare",
        "//systems/framework:context",
    ],
)

drake_cc_googletest(
    name = "curvilinear_joint_test",
    deps = [
        ":tree",
        "//common/test_utilities:expect_throws_message",
    ],
)

drake_cc_googletest(
    name = "revolute_joint_test",
    deps = [
        ":tree",
        "//common/test_utilities:expect_throws_message",
    ],
)

drake_cc_googletest(
    name = "ball_rpy_joint_test",
    deps = [
        ":tree",
    ],
)

drake_cc_googletest(
    name = "planar_joint_test",
    deps = [
        ":tree",
        "//common/test_utilities:expect_throws_message",
    ],
)

drake_cc_googletest(
    name = "prismatic_joint_test",
    deps = [
        ":tree",
    ],
)

drake_cc_googletest(
    name = "screw_joint_test",
    deps = [
        ":tree",
    ],
)

drake_cc_googletest(
    name = "universal_joint_test",
    deps = [
        ":tree",
        "//common/test_utilities:expect_throws_message",
    ],
)

drake_cc_googletest(
    name = "weld_joint_test",
    deps = [
        ":tree",
        "//common/test_utilities:expect_no_throw",
    ],
)

drake_cc_googletest(
    name = "quaternion_floating_joint_test",
    deps = [
        ":tree",
        "//common/test_utilities:expect_no_throw",
        "//common/test_utilities:expect_throws_message",
    ],
)

drake_cc_googletest(
    name = "rpy_floating_joint_test",
    deps = [
        ":tree",
        "//common/test_utilities:eigen_matrix_compare",
        "//common/test_utilities:expect_no_throw",
    ],
)

drake_cc_googletest(
    name = "joint_actuator_test",
    deps = [
        ":tree",
        "//common/test_utilities",
    ],
)

drake_cc_googletest(
    name = "geometry_spatial_inertia_test",
    data = [
        "//geometry:test_obj_files",
        "//geometry:test_vtk_files",
        "//multibody/parsing:test_models",
    ],
    deps = [
        ":geometry_spatial_inertia",
        "//common:find_resource",
        "//common/test_utilities:eigen_matrix_compare",
        "//common/test_utilities:expect_throws_message",
        "//geometry:shape_specification",
        "//geometry/proximity:make_box_mesh",
        "//geometry/proximity:triangle_surface_mesh",
    ],
)

add_lint_tests()
